package com.openlogic.common.logic.run;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.event.AppBeanLoadEndEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson2.JSON;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.openlogic.common.core.utils.DateUtils;
import com.openlogic.common.logic.constants.RuleConstants;
import com.openlogic.common.logic.node.enums.NodeExecEnums;
import com.openlogic.common.logic.node.factory.NodeExecFactory;
import com.openlogic.common.logic.utils.NumericRegxUtils;
import com.openlogic.common.logic.utils.StackExceptionUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
* @ClassName: ExecResultNodeHandler
* @Description: 计算节点运行执行器
* @author weiyongpeng
* @date 2024年7月17日 上午9:12:36
 */
@Component
public class ExecResultNodeHandler extends ExecRuleHandler{
	
	private static final Logger logger = LoggerFactory.getLogger(ExecResultNodeHandler.class);

	@Override
	public JSONObject typeRun(JSONArray resultArray1,JSONArray nodeArray,JSONArray lineArray,JSONObject inputjson,JSONArray areaArray,String areaFirst,String ruleId,StringBuffer reason,Map<String,Object> map) {
		JSONObject reJson = new JSONObject();
		logger.info("ResultNode Begin Run Starting...");
		// 默认节点解析后的数据
		logger.info("typeRun=====" +  resultArray1.toString());
		reJson = recRunForNode(resultArray1,nodeArray,lineArray,inputjson,areaArray,areaFirst,ruleId,reason,map);	
		return reJson;
	}

	/**
	* 描述：迭代节点执行
	* @Title: recRunForDefault
	* @param resultArray1
	* @param nodeArray
	* @param lineArray
	* @param inputjson
	* @param areaArray
	* @param areaFirst
	* @param ruleId
	* @param reason
	* @param map
	* @return
	* @author weiyongpeng
	* @date  2024年7月17日 上午10:29:23
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	protected JSONObject recRunForNode(JSONArray resultArray1, JSONArray nodeArray, JSONArray lineArray,
			JSONObject inputjson, JSONArray areaArray, String areaFirst, String ruleId, StringBuffer reason,
			Map<String, Object> map) {
		Map<Object,Object> inParam = new HashMap<>();
		Map<Object,Object> outParam = new HashMap<>();
	    for (Object ijo : inputjson.entrySet()){
	    	if(!((Map.Entry)ijo).getKey().toString().equals("everyNodeList") && !((Map.Entry)ijo).getKey().toString().equals("areaInfo") ) {
	    		inParam.put(((Map.Entry)ijo).getKey().toString().replaceAll("\"", ""), ((Map.Entry)ijo).getValue().toString().replaceAll("\"", ""));
	    	}
	    }
		// 开始执行时间
		Date startDate = DateUtils.getNowDate();
		String startExecuateTime = DateUtils.formatDate(startDate, DateUtils.YYYY_MM_DD_HH_MM_SS);
		// 异常信息
		String errorMsg = "";
		// 流程执行结束的json对象
		JSONObject reJson = new JSONObject();
		// 发生异常的时候返回的json对象
		JSONObject errorJson = new JSONObject();
		// 下一个可执行节点的json对象
		JSONObject nextResult = new JSONObject();
		try {
			String successString = ((JSONObject)resultArray1.get(3)).get("success").toString();
			String[] successlist =  successString.split("&@");
			for(int k=0,succlength=successlist.length;k<succlength;k++) {
				String[] succlist1 = successlist[k].split("=");
				for(int h=0,succlength1=succlist1.length;h<succlength1;h++) {
					if(h==0) {
						//遍历替换success中的变量
						inputjson = sortJson(inputjson);
						Map<String, Object> env = inputjson;
						//执行自定义函数
						if(succlist1[1].contains("(")||succlist1[1].contains("+")||succlist1[1].contains("-")||succlist1[1].contains("*")||succlist1[1].contains("/")) {
							String[] temp = succlist1[1].split("\\^");
							String tempStr = "";
							for(int i =0;i<temp.length;i++) {
								if(temp[i].indexOf("com")!=-1) {
									tempStr+=temp[i];
								}else {
									Iterator<String> it1 = inputjson.keys(); 
									while(it1.hasNext()){
										// 获得key
										String key = it1.next(); 
										if(temp[i].replaceAll("\\@", "").split("\\.").length >= 2) {
											List<String> funcVars = Arrays.asList(temp[i].replaceAll("\\(", "").replaceAll("\\)", "").split("\\,"))
																		.stream()
																		.filter(x -> !NumericRegxUtils.isNumber(x))
																		.collect(Collectors.toList());
											for (String var : funcVars) {
												String[] sqlSplit = var.replaceAll("\\@", "").split("\\.");
												if(sqlSplit.length < 2) break;
												// 取出需要对比的字段
												String compareVar = sqlSplit[1];
												List<Map<String,String>> columnValueList = new ArrayList<>();
												if (sqlSplit[0].equals(key)) {
													List<Map<String,Object>> listObjectFir = (List<Map<String,Object>>) com.alibaba.fastjson.JSONArray.parse((String)sqlCache.get(key));
													if (CollectionUtils.isEmpty(listObjectFir)) {
														// 根据参数名称查询SQL参数
														listObjectFir = selectRuleSqlParamRes(inputjson, key, env);
													}
													columnValueList = listObjectFir.stream().filter(mapF -> Optional.ofNullable(mapF.get(compareVar)).isPresent()).map(mapV -> {
														Map<String,String> m = new HashMap<>();
														Object value = mapV.get(compareVar);
														m.put(compareVar, String.valueOf(value));
														return m;
													}).collect(Collectors.toList());
													temp[i] = temp[i].replaceAll(var, var.replaceAll("\\@", ""));
													// se.put(var.replaceAll("\\@", ""),com.alibaba.fastjson.JSONArray.parse(JSON.toJSONString(columnValueList)));
													env.put(var.replaceAll("\\@", ""), columnValueList);
													break;
												}
											}
										}else if(temp[i].contains("@" + key + "@")) {
											temp[i] = temp[i].replaceAll("\\@" + key + "\\@", key);
											List<Map<String, Object>> listObjectFir = Optional
													.ofNullable(sqlCache.get(key)).isPresent()
															? (List<Map<String, Object>>) com.alibaba.fastjson.JSONArray
																	.parse((String) sqlCache.get(key))
															: selectRuleSqlParamRes(inputjson, key, env);
//											se.put(key, listObjectFir);
											env.put(key, listObjectFir);
											break;
										}
									}
									tempStr+=temp[i];
								}
							}
							try {
								Expression compile = AviatorEvaluator.compile(tempStr,true);
								Object res = compile.execute(env);
								//赋值
								inputjson.put(succlist1[0], res);
							} catch (Exception e) {
								errorMsg = StackExceptionUtils.getExceptionType(e).toString();
								logger.error("异常信息:{}",e.getMessage());
							}
						}else {
							Iterator<String> it1 = inputjson.keys(); 
							while(it1.hasNext()){
								// 获得key
								String key = it1.next(); 
								//特别注意数字不带单引号，字符串带单引号
								succlist1[1] = succlist1[1].contains("@" + key + "@") ? Optional.ofNullable(sqlCache.get(key)).isPresent() ? (String)sqlCache.get(key) : JSON.toJSONString(selectRuleSqlParamRes(inputjson, key, env)) : succlist1[1].replaceAll(key,inputjson.getString(key));
//								succlist1[1] = succlist1[1].replaceAll(key, NumericRegxUtils.isNumber(inputjson.getString(key))?inputjson.getString(key):"'"+inputjson.getString(key)+"'");
							}
							//赋值
							inputjson.put(succlist1[0], succlist1[1]);
						}
					}
				}
			}
		} catch (Exception e) {
			logger.error("异常信息:{}",e.getMessage());
			errorMsg = StackExceptionUtils.getExceptionType(e).toString();
		}
		
		if (errorMsg == null || errorMsg.equals("")) {
			for (Object ijo : inputjson.entrySet()){
		    	if(!((Map.Entry)ijo).getKey().toString().equals("everyNodeList") && !((Map.Entry)ijo).getKey().toString().equals("areaInfo") ) {
		    		outParam.put(((Map.Entry)ijo).getKey().toString().replaceAll("\"", ""), ((Map.Entry)ijo).getValue().toString().replaceAll("\"", ""));
		    	}
		    }
			reJson = inputjson;
			if(resultArray1.get(2).equals("area")) {
				if(areaFirst.equals("")) {//判断是否是循环的第一个 节点
					areaFirst = resultArray1.getString(0);
					reJson.put("areaFirst", areaFirst);
				}
			}		
			//寻找下级节点
			nextResult = runNextNode(resultArray1,nodeArray,lineArray,inputjson,areaArray,areaFirst,ruleId,0,reason,map,startDate,inParam,outParam);
			if(!nextResult.toString().equals("{}")) {
				return nextResult;
			}
		}else {
			Map<Object,Object> errorMap = new HashMap<>();
			errorMap.put("msg", errorMsg);
			errorJson = JSONObject.fromObject(errorMap);
			// 执行异常信息
			nextResult = runNextNodeThrow(resultArray1,nodeArray,lineArray,inputjson,areaArray,areaFirst,ruleId,0,reason,map,startDate,inParam,errorJson);
			if(!nextResult.toString().equals("{}")) {
				return nextResult;
			}
		}
		// 结束执行时间
		Date endDate = DateUtils.getNowDate();
		String endExecuateTime = DateUtils.formatDate(endDate, DateUtils.YYYY_MM_DD_HH_MM_SS);
		reJson.put("startExecTime", startExecuateTime);
		reJson.put("endExecTime", endExecuateTime);
		reJson.put("execTotalTimeMills", "耗时: "+(endDate.getTime() - startDate.getTime())+" 毫秒");
		reJson.put("execStatus", RuleConstants.NODE_EXEC_SUCCESS);
		//添加轨迹信息
		return reJson;
	}

	@Override
	public void onEvent(AppBeanLoadEndEvent event) throws Throwable {
		NodeExecFactory.register(NodeExecEnums.RESULT_NODE.getCode(), this);
	}

}
